from typing import Optional, Union, BinaryIO
from pathlib import Path
import mimetypes
import tempfile
import aiofiles
from .logger import get_logger

logger = get_logger(__name__)


class FileParser:
    """多格式文件解析器."""
    
    SUPPORTED_TYPES = {
        'text/plain': '_parse_text',
        'text/markdown': '_parse_markdown',
        'application/pdf': '_parse_pdf',
        'application/msword': '_parse_doc',
        'application/vnd.openxmlformats-officedocument.wordprocessingml.document': '_parse_docx',
        'application/vnd.ms-excel': '_parse_xls',
        'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': '_parse_xlsx',
        'image/jpeg': '_parse_image',
        'image/png': '_parse_image',
        'image/gif': '_parse_image'
    }
    
    def __init__(self):
        self.logger = logger
    
    async def parse_file(self, file_path: Union[str, Path], mime_type: Optional[str] = None) -> str:
        """解析文件并返回文本内容."""
        
        file_path = Path(file_path)
        if not file_path.exists():
            raise FileNotFoundError(f"文件不存在: {file_path}")
        
        # 检测MIME类型
        if not mime_type:
            mime_type, _ = mimetypes.guess_type(str(file_path))
        
        if not mime_type or mime_type not in self.SUPPORTED_TYPES:
            raise ValueError(f"不支持的文件类型: {mime_type}")
        
        parser_method = getattr(self, self.SUPPORTED_TYPES[mime_type])
        
        try:
            self.logger.info(f"解析文件: {file_path}, 类型: {mime_type}")
            content = await parser_method(file_path)
            self.logger.info(f"文件解析成功，提取文本长度: {len(content)}")
            return content
        except Exception as e:
            self.logger.error(f"文件解析失败 {file_path}: {str(e)}")
            raise
    
    async def _parse_text(self, file_path: Path) -> str:
        """解析纯文本文件."""
        async with aiofiles.open(file_path, 'r', encoding='utf-8') as f:
            return await f.read()
    
    async def _parse_markdown(self, file_path: Path) -> str:
        """解析Markdown文件."""
        try:
            import markdown
            async with aiofiles.open(file_path, 'r', encoding='utf-8') as f:
                md_content = await f.read()
            
            # 转换markdown为纯文本（移除格式化）
            html = markdown.markdown(md_content)
            # 这里可以使用BeautifulSoup进一步清理HTML标签
            return md_content  # 暂时返回原始内容
        except ImportError:
            # 如果没有markdown库，直接返回原始内容
            return await self._parse_text(file_path)
    
    async def _parse_pdf(self, file_path: Path) -> str:
        """解析PDF文件."""
        try:
            import PyPDF2
            text_content = []
            
            with open(file_path, 'rb') as file:
                pdf_reader = PyPDF2.PdfReader(file)
                for page in pdf_reader.pages:
                    text_content.append(page.extract_text())
            
            return '\n'.join(text_content)
        except Exception as e:
            raise Exception(f"PDF解析失败: {str(e)}")
    
    async def _parse_doc(self, file_path: Path) -> str:
        """解析DOC文件 (需要额外工具)."""
        raise NotImplementedError("DOC文件解析需要额外配置")
    
    async def _parse_docx(self, file_path: Path) -> str:
        """解析DOCX文件."""
        try:
            from docx import Document
            doc = Document(file_path)
            text_content = []
            
            for paragraph in doc.paragraphs:
                text_content.append(paragraph.text)
            
            return '\n'.join(text_content)
        except Exception as e:
            raise Exception(f"DOCX解析失败: {str(e)}")
    
    async def _parse_xls(self, file_path: Path) -> str:
        """解析XLS文件."""
        raise NotImplementedError("XLS文件解析需要额外配置")
    
    async def _parse_xlsx(self, file_path: Path) -> str:
        """解析XLSX文件."""
        try:
            from openpyxl import load_workbook
            workbook = load_workbook(file_path)
            text_content = []
            
            for sheet_name in workbook.sheetnames:
                sheet = workbook[sheet_name]
                text_content.append(f"=== {sheet_name} ===")
                
                for row in sheet.iter_rows(values_only=True):
                    row_text = '\t'.join([str(cell) if cell is not None else '' for cell in row])
                    if row_text.strip():
                        text_content.append(row_text)
            
            return '\n'.join(text_content)
        except Exception as e:
            raise Exception(f"XLSX解析失败: {str(e)}")
    
    async def _parse_image(self, file_path: Path) -> str:
        """解析图片文件 (OCR)."""
        # 这里需要OCR功能，暂时返回基础信息
        return f"图片文件: {file_path.name} (OCR功能待实现)"